home *** CD-ROM | disk | FTP | other *** search
/ Aminet 1 (Walnut Creek) / Aminet - June 1993 [Walnut Creek].iso / usenet / sources / volume2 / keyboard / dasm20.3 < prev    next >
Text File  |  1992-04-19  |  43KB  |  1,503 lines

  1. Path: xanth!nic.MR.NET!tank!ncar!mailrus!ulowell!page
  2. From: page@swan.ulowell.edu (Bob Page)
  3. Newsgroups: comp.sources.amiga
  4. Subject: v02i029:  dasm - small systems cross assembler V2.0, Part03/03
  5. Message-ID: <9880@swan.ulowell.edu>
  6. Date: 26 Oct 88 17:23:45 GMT
  7. Organization: University of Lowell, Computer Science Dept.
  8. Lines: 1492
  9. Approved: page@swan.ulowell.edu
  10.  
  11. Submitted-by: dillon@cory.berkeley.edu (Matt Dillon)
  12. Posting-number: Volume 2, Issue 29
  13. Archive-name: languages/dasm20.3
  14.  
  15. # This is a shell archive.  Remove anything before this line
  16. # then unpack it by saving it in a file and typing "sh file"
  17. # (Files unpacked will be owned by you and have default permissions).
  18. # This archive contains the following files:
  19. #    README
  20. #    TODO
  21. #    doc/ftohex.doc
  22. #    doc/dasm.doc
  23. #    src/test.asm
  24. #    src/tags
  25. #    src/test
  26. #    src/mne68705.c
  27. #    src/ftohex.c
  28. #    src/symbols.c
  29. #
  30. if `test ! -s README`
  31. then
  32. echo "writing README"
  33. cat > README << '\Rogue\Monster\'
  34.  
  35.     DASM    V2.0
  36.  
  37.     (c)Copyright 1988 Matthew Dillon, All Rights Reserved.
  38.        Freely Distributable (for non-profit) ONLY.  No redistribution
  39.        of any modified text files or redistribution of a subset of the
  40.        source is allowed.  Redistribution of modified binaries IS allowed
  41.        under the above terms.
  42.  
  43.        Circumvention of said terms requires the permission of the Author
  44.        via US Mail.
  45.  
  46.        Matthew Dillon
  47.        891 Regal Rd.
  48.        Berkeley, Ca. 94708
  49.  
  50.  
  51. COMPILATION
  52.  
  53.     The source code assumes that integers are LONG WORDS.  All expression
  54.     computation is carried out with 32 bit ints.  Additionaly, the
  55.     correct implementation of STDIO functions is assumed (no translation).
  56.  
  57.     This code will compile with little or no modification on Amiga and UNIX
  58.     systems.
  59.  
  60. CONVERSION TO IBM:
  61.  
  62.     FTOHEX should compile on an IBM-PC, DASM will not.
  63.  
  64.     Compilers on IBM PC's are usually not very sophisticated (at least not
  65.     compared to what I'm used to), and must deal with two major problems:
  66.     (1) 16 bit integers, (2) incompatible text file format with CR-LF
  67.     instead of just LF.  To convert to an IBM PC compiler, you must
  68.  
  69.     (A) Declare all unspecified functions as returning a LONG
  70.     (B) Put in extern's in ASM.H for all unspecified functions
  71.     declaring them as returning a LONG
  72.     (C) Change any int declarations to long
  73.     (D) Ensure all expressions are carried out on longwords (especially
  74.     expression handling)
  75.     (E) Ensure all function calls pass longwords by adding a (long) cast
  76.     or 'L' at the end of longword constants.
  77.     (F) Ensure STDIO for any binary files (the output file) does NOT
  78.     do data translation.
  79.  
  80.     Alternately, you can throw away your IBM and go for a better machine.
  81.  
  82.  
  83.     DASM:    The Assembler
  84.  
  85.     FTOHEX:    Convert assembler output files to intel-hex format
  86.  
  87.  
  88. FEATURES
  89.  
  90.     -fast
  91.     -processor selection (use same assembler for many processors)
  92.     -multi-pass (more than two passes if required)
  93.     -conditional assembly
  94.     -local labels (VERY local labels)
  95.     -macro capability (no stacking limit)
  96.     -symbolic expression capability
  97.     -addressing mode overides
  98.     -arbitrary number of named segments
  99.     -many pseudo-ops for repeat loops, data generation, etc....
  100.  
  101.  
  102. PROCESSORS
  103.  
  104.       --------------- CURRENTLY SUPPORTED MICROPROCESSORS ---------------
  105.  
  106.  
  107. 6502:        ORDER LSB,MSB   A<7:0> X<7:0> Y<7:0>    RelAddr:   .+ilen+offset
  108. 68705:        ORDER MSB,LSB   A<7:0> X<7:0>        RelAddr:   .+ilen+offset
  109. 6803/HD6303:ORDER MSB,LSB   A<7:0> B<7:0> X<15:0>   RelAddr:   .+ilen+offset
  110.  
  111.  
  112. ADDRESSING MODES        6502    68705    6803/HD6303
  113. BYTES
  114.  
  115.  2  implied            x    x    x
  116.  2  immediate.8     #byte    x    x    x
  117.  3  immediate.16    #word            x
  118.  2  byteaddr        byte    x    x    x
  119.  2  byteaddr,x        byte,x    x    x    x
  120.  2  byteaddr,y        byte,y    x
  121.  3  wordaddr        word    x    x    x
  122.  3  wordaddr,x        word,x    x    x
  123.  3  wordaddr,y        word,y    x
  124.  2  relative        byte    x    x    x
  125.  2  ind.byte.x        (byte,x)    x
  126.  2  ind.byte.y        (byte),y    x
  127.  3  ind.word        (word)      x
  128.  1  0,x         [0],x        x
  129.  2  bitmod        #no,badr        x        baseinst + 2*bitno
  130.  3  bitbramod        #no,badr,rel    x        baseinst + 2*bitno
  131.  
  132. NOTE:    HD6303 instruction extensions over the 6803 are:
  133.         AIM OIM EIM TIM XGDX SLP
  134.  
  135. \Rogue\Monster\
  136. else
  137.   echo "will not over write README"
  138. fi
  139. if [ `wc -c README | awk '{printf $1}'` -ne 3211 ]
  140. then
  141. echo `wc -c README | awk '{print "Got " $1 ", Expected " 3211}'`
  142. fi
  143. if `test ! -s TODO`
  144. then
  145. echo "writing TODO"
  146. cat > TODO << '\Rogue\Monster\'
  147.  
  148.     -DS.W   , allow word-sized fill characters
  149.     -DS.L   , allow long-sized fill characters
  150.  
  151. \Rogue\Monster\
  152. else
  153.   echo "will not over write TODO"
  154. fi
  155. if [ `wc -c TODO | awk '{printf $1}'` -ne 96 ]
  156. then
  157. echo `wc -c TODO | awk '{print "Got " $1 ", Expected " 96}'`
  158. fi
  159. if `test ! -d doc`
  160. then
  161.   mkdir doc
  162.   echo "mkdir doc"
  163. fi
  164. if `test ! -s doc/ftohex.doc`
  165. then
  166. echo "writing doc/ftohex.doc"
  167. cat > doc/ftohex.doc << '\Rogue\Monster\'
  168.  
  169. FTOHEX    Convert assembly output file to INTEL-HEX format suitable for, say,
  170. a GTEK prom programmer.
  171.  
  172.     FTOHEX format infile outfile
  173.  
  174. Example:
  175.     DASM -f2 example.asm -oram:example.out
  176.     FTOHEX 2 ram:example.out ram:example.hex
  177.  
  178.     This program converts and output file generated by DASM to the Intel
  179.     hex-ascii format.  You must specify the format you used when you
  180.     assembled the source for FTOHEX to properly read the out file.
  181.     Generally format 2 is used for assembly (see DASM.DOC) as this
  182.     generates the smallest hex file.
  183.  
  184.  
  185.  
  186. \Rogue\Monster\
  187. else
  188.   echo "will not over write doc/ftohex.doc"
  189. fi
  190. if [ `wc -c doc/ftohex.doc | awk '{printf $1}'` -ne 549 ]
  191. then
  192. echo `wc -c doc/ftohex.doc | awk '{print "Got " $1 ", Expected " 549}'`
  193. fi
  194. if `test ! -s doc/dasm.doc`
  195. then
  196. echo "writing doc/dasm.doc"
  197. cat > doc/dasm.doc << '\Rogue\Monster\'
  198.  
  199.  
  200. DOCUMENTATION FOR DASM V2.11, a high level macro cross assembler for:
  201.  
  202.     -6502
  203.     -68705
  204.     -6803
  205.     -HD6303 (extension of 6803)
  206.  
  207.     Soon will work for 68HC11 (next ver)
  208.  
  209.     (C)Copyright 1987,1988 Matthew Dillon, All Rights Reserved
  210.  
  211.     Publicly distributable for non-profit only.  Must be distributed
  212.     as is, with NO CHANGES to the documentation or code.  If you want
  213.     your (general) changes to be made part of the distribution, send
  214.     them to me.
  215.  
  216.     Over the last year my work has included writing software to drive small
  217.     single-chip microcomputers for various things (remote telemetry units,
  218.     for instance).  I have had need to program quite a few different
  219.     processors over that time.
  220.  
  221.     At the beginning, I used an awful macro assembler running on an IBM-PC.
  222.     I *really* wanted to do it on my Amiga.  Thus the writing of this
  223.     program.
  224.  
  225.     Feel free to suggest other similar processors for me to add to the list!
  226.     The processor type is specified with a pseudo-op (see below).  This
  227.     assembler produces only binary output in one of three formats described
  228.     below.  In general, one has a master assembly file which INCLUDEs all
  229.     the modules.
  230.  
  231.     Also provided is FTOHEX which converts an output file in one of the
  232.     three formats to an intel-hex format suitable for many intelligent
  233.     prom programmers (I have a GTEK).
  234.  
  235.     YES it's packed with features!
  236.  
  237. FEATURES:
  238.  
  239.     -fast assembly
  240.     -supports several common 8 bit processor models (NOT 8086, thank god!)
  241.     -takes as many passes as needed
  242.     -automatic checksum generation, special symbol '...'
  243.     -several binary output formats available.  Format 2 allows reverse
  244.      indexed origins.
  245.     -multiple segments, BSS segments (no generation), relocatable origin.
  246.     -expressions, as in C but [] is used instead of () for parenthesis.
  247.      (all expressions are computed with 32 bit integers)
  248.     -no real limitation on label size, label values are 32 bits.
  249.     -complex pseudo ops, repeat loops, macros, etc....
  250.  
  251.  
  252. COMMAND LINE:
  253.  
  254.     asm srcfile [options]
  255.  
  256.     options:    -f#     select output format 1-3 (default 1, see below)
  257.             -oname  select output file name (else a.out)
  258.             -lname  select list file name   (else none generated)
  259.             -sname  select symbol dump file (else none generated)
  260.             -v#     select verboseness 0-4 (default 0, see below)
  261.             -d        debug mode
  262.             -DSYMBOL            predefine a symbol, set to 0
  263.             -DSYMBOL=EXPRESSION     predefine a symbol, set to exp
  264.  
  265.     Note: file names should be in RAM: for speed.  If a list file is
  266.     specified, it should be in the RAM: disk (assembly is slowed down
  267.     quite a bit anyway).
  268.  
  269.     Example:    asm master.asm -f2 -oram:out -lram:list -v3 -DVER=4
  270.  
  271. FORMAT OPTIONS:
  272.  
  273.     1  (DEFAULT)
  274.  
  275.     The output file contains a two byte origin in LSB,MSB order, then
  276.     data until the end of the file.
  277.  
  278.     Restrictions:    Any instructions which generate output (within an
  279.     initialized segment) must do so with an ascending PC.  Initialized
  280.     segments must occur in ascending order.
  281.  
  282.     2  RAS (Random Access Segment)
  283.  
  284.     The output file contains one or more hunks.  Each hunk consists
  285.     of a 2 byte origin (LSB,MSB), 2 byte length (LSB,MSB), and that
  286.     number of data bytes.  The hunks occur in the same order as
  287.     initialized segments in the assembly.  There are no restrictions
  288.     to segment ordering (i.e. reverse indexed ORG statements are
  289.     allowed).  The next hunk begins after the previous hunk's data,
  290.     until the end of the file.
  291.  
  292.     3  RAW (Raw)
  293.  
  294.     The output file contains data only (format #1 without the 2 byte
  295.     header).  Restrictions are the same as for format #1.
  296.  
  297.     Format 3    RAW (Raw format)
  298.         Same as format 1, but NO header origin is generated.  You get
  299.         nothing but data.
  300.  
  301. VERBOSE OPTIONS:
  302.  
  303.     0    (default)
  304.  
  305.     Only warnings and errors are generated
  306.  
  307.     1
  308.     -Segment list information generated after each pass
  309.     -Include file names are displayed
  310.     -statistics on why the assembler is going to make another pass
  311.         R1,R2 reason code: R3
  312.         where R1 is the number of times the assembler encountered
  313.         something requiring another pass to resolve.  R2 is the
  314.         number of references to unknown symbols which occured in the
  315.         pass (but only R1 determines the need for another pass).  R3
  316.         is a BITMASK of the reasons why another pass is required.
  317.         See the end of this document for bit designations.
  318.  
  319.     2
  320.     mismatches between program labels and equates are displayed
  321.     on every pass (usually none occur in the first pass unless you
  322.     have re-declared a symbol name).
  323.  
  324.     displayed information for symbols:
  325.         ???? = unknown value
  326.         str  = symbol is a string
  327.         eqm  = symbol is an eqm macro
  328.         (r)  = symbol has been referenced
  329.         (s)  = symbol created with SET or EQM pseudo-op
  330.  
  331.     3
  332.         Unresolved and unreferenced symbols are displayed every pass
  333.         (unsorted, sorry)
  334.  
  335.     4
  336.         An entire symbol list is displayed every pass to STDOUT.
  337.         (unsorted, sorry)
  338.  
  339. PROCESSOR MODEL:
  340.  
  341.     The processor model is chosen with the PROCESSOR pseudo-op and should
  342.     be the first thing you do in your assembly file.   Different processor
  343.     models use different integer formats (see below).  The word order does
  344.     not effect the headers in the output files (-f1 and -f2), which are
  345.     always LSB,MSB.  The word ordering effects all address, word, and
  346.     long generation.
  347.  
  348.     Only one PROCESSOR pseudo-op may be declared in the entire assembly,
  349.     and should be the first thing encountered.
  350.  
  351.     -6502        LSB,MSB
  352.     -68HC11     MSB,LSB (next release)
  353.     -68705        MSB,LSB
  354.     -6803        MSB,LSB
  355.     -HD6303     MSB,LSB
  356.  
  357. SEGMENTS:
  358.     The SEG pseudo-op creates/sets the current segment.  Each segment has
  359.     it's own origin and is optionally an 'uninitialized' segment.
  360.     Unitialized segments produce no output and have no restrictions.  This
  361.     is useful for determining the size of a certain assembly sequence
  362.     without generating code, and for assigning RAM to labels.
  363.  
  364.     'Initialized' segments produce output.  The following should be
  365.     considered when generating roms:
  366.  
  367.     (1) The default fill character when using ORG (and format 1 or 3) to
  368.     skip forward is 00.  This is a GLOBAL default and effects all
  369.     segments.  See ORG.
  370.  
  371.     (2) The default fill character for DS is 00 and is independant of
  372.     the default fill character for ORG (see DS).
  373.  
  374. GENERAL:
  375.     Most everything is recursive.  You cannot have a macro DEFINITION
  376.     within a macro definition, but can nest macro calls, repeat loops,
  377.     and include files.
  378.  
  379.     The other major feature in this assembler is the SUBROUTINE pseudo-op,
  380.     which logically separates local labels (starting with a dot).  This
  381.     allows you to reuse label names (for example, .1 .fail) rather than
  382.     think up crazy combinations of the current subroutine to keep it all
  383.     unique.
  384.  
  385.     Almost nothing need be resolved in pass 1.    The assembler will make
  386.     multiple passes in an attempt to resolve the assembly (including just
  387.     one pass if everything is resolved immediately).
  388.  
  389.  
  390. PSEUDOPS:
  391.  
  392.     INCLUDE     "name"
  393.  
  394.         Include another assembly file.
  395.  
  396. [label] SEG[.U]     name
  397.  
  398.         This sets the current segment, creating it if neccessary.  If
  399.         a .U extension is specified on segment creation, the segment
  400.         is an UNINITIALIZED segment.  The .U is not needed when going
  401.         back to an already created uninitialized segment, though it
  402.         makes the code more readable.
  403.  
  404. [label] DC[.BWL]    exp,exp,exp ...
  405.  
  406.         Declare data in the current segment.  No output is generated if
  407.         within a .U segment.  Note that the byte ordering for the
  408.         selected processor is used for each entry.
  409.  
  410.         The default size extension is a byte.
  411.  
  412. [label] DS[.BWL]    exp[,filler]
  413.  
  414.         declare space (default filler is 0). Data is not generated if
  415.         within an uninitialized segment.  Note that the number of bytes
  416.         generated is exp * entrysize (1,2, or 4)
  417.  
  418.         The default size extension is a byte.
  419.  
  420.         Note that the default filler is always 0 (has nothing to do
  421.         with the ORG default filler).
  422.  
  423. [label] DV[.BWL]    eqmlabel exp,exp,exp....
  424.  
  425.         This is equivalent to DC, but each exp in the list is passed
  426.         through the symbolic expression specified by the EQM label.
  427.         The expression is held in a special symbol dotdot '..' on each
  428.         call to the EQM label.
  429.  
  430.         See EQM below
  431.  
  432. [label] HEX        hh hh hh..
  433.  
  434.         This sets down raw HEX data.  Spaces are optional between bytes.
  435.         NO EXPRESSIONS are allowed.  Note that you do NOT place a $
  436.         in front of the digits.  This is a short form for creating
  437.         tables compactly.  Data is always layed down on a byte-by-byte
  438.         basis.
  439.  
  440.         Example:        HEX 1A45 45 13254F 3E12
  441.  
  442.     ERR
  443.  
  444.         Abort assembly.
  445.  
  446. [label] ORG        exp[,DefaultFillVal]
  447.  
  448.         This pseudop sets the current origin.  You can also set the
  449.         global default fill character (a byte value) with this
  450.         pseudoop.  NOTE that no filler is generated until the first
  451.         data-generating opcode/psueoop is encountered after this one.
  452.         Sequences like:
  453.  
  454.         org  0,255
  455.         org  100,0
  456.         org  200
  457.         dc   23
  458.  
  459.         will result in 200 zero's and a 23. This allows you to specify
  460.         some ORG, then change your mind and specify some other (lower
  461.         address) ORG without causing an error (assuming nothing is
  462.         generated inbetween).
  463.  
  464.         Normally, DS and ALIGN are used to generate specific filler
  465.         values.
  466.  
  467. [label] RORG        exp
  468.  
  469.         This activates the relocatable origin.  All generated
  470.         addresses, including '.', although physically placed at the
  471.         true origin, will use values from the relocatable origin.
  472.         While in effect both the physical origin and relocatable origin
  473.         are updated.
  474.  
  475.         The relocatable origin can skip around (no limitations).  The
  476.         relocatable origin is a function of the segment.  That is, you
  477.         can still SEG to another segment that does not have a
  478.         relocatable origin activated, do other (independant) stuff
  479.         there, and then switch back to the current segment and continue
  480.         where you left off.
  481.  
  482.     PROCESSOR model
  483.  
  484.         do not quote.  model is one of: 6502,6803,HD6303,68705,68HC11
  485.         Can only be executed once, and should be the first thing
  486.         encountered by the assembler.  the 68HC11 will be available
  487.         next release.
  488.  
  489.     ECHO exp,exp,exp
  490.  
  491.         The expressions (which may also be strings), are echod on the
  492.         screen and into the list file
  493.  
  494. [label] REND
  495.  
  496.         Deactivate the relocatable origin for the current segment.
  497.         Generation uses the real origin for reference.
  498.  
  499. [label] ALIGN        N[,fill]
  500.  
  501.         Align the current PC to an N byte boundry.    The default
  502.         fill character is always 0, and has nothing to do with
  503.         the default fill character specifiable in an ORG.
  504.  
  505. [label] SUBROUTINE  name
  506.  
  507.         This isn't really a subroutine, but a boundry between sets of
  508.         temporary labels (which begin with a dot).  Temporary label
  509.         names are unique within segments of code bounded by SUBROUTINE:
  510.  
  511.         CHARLIE subroutine
  512.             ldx #10
  513.         .1    dex
  514.             bne .1
  515.         BEN    subroutine
  516.             ldx #20
  517.         .qq    dex
  518.             bne .qq
  519.  
  520.         Automatic temporary label boundries occur for each macro level.
  521.         Usually temporary labels are used in macros and within actual
  522.         subroutines (so you don't have to think up a thousand different
  523.         names)
  524.  
  525.  
  526. symbol    EQU        exp
  527.  
  528.         The expression is evaluated and the result assigned to the
  529.         symbol.
  530.  
  531. symbol    EQM        exp
  532.  
  533.         The STRING representing the expression is assigned to the
  534.         symbol.  Occurances of the label in later expressions causes
  535.         the string to be evaluated for each occurance.  Also used in
  536.         conjuction with the DV psuedo-op.
  537.  
  538. symbol    SET        exp
  539.  
  540.         Same as EQU, but the symbol may be reassigned later.
  541.  
  542.     MAC        name
  543.  
  544.         Declare a macro.  lines between MAC and ENDM are the macro.
  545.         You cannot recursively declare a macro.  You CAN recursively
  546.         use a macro (reference a macro in a macro).  No label is
  547.         allowed to the left of MAC or ENDM.
  548.  
  549.         Arguments passed to macros are referenced with: {#}.  The first
  550.         argument passed to a macro would thus be {1}.  You should
  551.         always use LOCAL labels (.name) inside macros which you use
  552.         more than once. {0} represents an EXACT substitution of the
  553.         ENTIRE argument line.
  554.  
  555.     ENDM
  556.  
  557.         end of macro def.  NO LABEL ALLOWED ON THE LEFT!
  558.  
  559.     MEXIT
  560.  
  561.         Used in conjuction with conditionals.  Exits the current macro
  562.         level.
  563.  
  564. [label] IFCONST     exp
  565.  
  566.         Is TRUE if the expression result is defined,  FALSE otherwise
  567.         and NO error is generated if the expression is undefined.
  568.  
  569. [label] IFNCONST    exp
  570.  
  571.         Is TRUE if the expression result is undefined, FALSE otherwise
  572.         and NO error is generated if the expression is undefined.
  573.  
  574. [label] IF        exp
  575.  
  576.         Is TRUE if the expression result is defined AND non-zero.
  577.         Is FALSE if the expression result is defined AND zero.
  578.         Neither IF or ELSE will be executed if the expression result
  579.         is undefined.  If the expression is undefined, another assembly
  580.         pass is automatically taken.
  581.  
  582. [label] ELSE
  583.  
  584.         ELSE the current IF.
  585.  
  586. [label] ENDIF
  587. [label] EIF
  588.  
  589.         Terminate an IF. ENDIF and EIF are equivalent.
  590.  
  591. [label] REPEAT        exp
  592. [label] REPEND
  593.  
  594.         Repeat code between REPEAT/REPEND 'exp' times.  if exp == 0,
  595.         the code repeats forever.  exp is evaluated once.
  596.  
  597.         Y   SET     0
  598.             REPEAT  10
  599.         X   SET     0
  600.             REPEAT  10
  601.             DC        X,Y
  602.         X   SET     X + 1
  603.             REPEND
  604.         Y   SET     Y + 1
  605.             REPEND
  606.  
  607.         generates an output table:    0,0 1,0 2,0 ... 9,0  0,1 1,1 2,1
  608.         ... 9,1, etc...
  609.  
  610.         Labels within a REPEAT/REPEND should be temporary labels with a
  611.         SUBROUTINE pseudoop to keep them unique.
  612.  
  613.         The Label to the left of REPEND is assigned AFTER the loop
  614.         FINISHES.
  615.  
  616.  
  617. [label] XXX[.force] operand
  618.  
  619.         XXX is some mnemonic, not necessarily three characters long.
  620.         The .FORCE optional extension is used to force specific
  621.         addressing modes (see below).
  622.  
  623. GENERAL:
  624.  
  625.     The label will be set to the current ORG/RORG either before or after
  626.     a pseudo-op is executed.  Most of the time, the label to the left of a
  627.     pseudo-op is the current ORG/RORG. The following pseudo-op's labels are
  628.     created AFTER execution of the pseudo-op:
  629.  
  630.     SEG, ORG, RORG, REND, ALIGN
  631.  
  632. EXTENSIONS:
  633.  
  634.     FORCE extensions are used to force an addressing mode.  In some cases,
  635.     you can optimize the assembly to take fewer passes by telling it the
  636.     addressing mode.  Force extensions are also used with DS,DC, and DV
  637.     to determine the element size.  NOT ALL EXTENSIONS APPLY TO ALL
  638.     PROCESSORS!
  639.  
  640.     example:    lda.z   charlie
  641.  
  642.     i   -implied
  643.     ind -indirect word
  644.     0   -implied
  645.     0x  -implied indexing (0,x)
  646.     0y  -implied indexing (0,y)
  647.     b   -byte address
  648.     bx  -byte address indexed x
  649.     by  -byte address indexed y
  650.     w   -word address
  651.     wx  -word address indexed x
  652.     wy  -word address indexed y
  653.     l   -longword (4 bytes) (DS/DC/DV)
  654.     r   -relative
  655.     u   -uninitialized (SEG)
  656.  
  657.     First character equivalent substitutions:
  658.  
  659.     b z d        (byte, zeropage, direct)
  660.     w e a        (word, extended, absolute)
  661.  
  662.  
  663. ASSEMBLER PASSES:
  664.     The assembler may have to make several passes through the source
  665.     code to resolve all generation.  The number of passes is not
  666.     limited to two.  Since this may result in an unexpected, verbose
  667.     option 2, 3, and 4 have been provided to allow determination of the
  668.     cause. The assembler will give up if it thinks it can't do the
  669.     assembly in *any* number of passes.
  670.  
  671.     Error reporting could be better....
  672.  
  673.  
  674. EXPRESSIONS:
  675.     [] may be used to group expressions.  The precedense of operators
  676.     is the same as for the C language in almost all respects.  Use
  677.     brackets [] when you are unsure.  The reason () cannot be used to
  678.     group expressions is due to a conflict with the 6502 and other
  679.     assembly languages.
  680.  
  681.     Some operators, such as ||, can return a resolved value even if
  682.     one of the expressions is not resolved.   Operators are as follows:
  683.  
  684.     NOTE WELL!  Some operations will result in non-byte values when a
  685.     byte value was wanted.    For example:    ~1  is NOT $FF, but
  686.     $FFFFFFFF.  Preceding it with a < (take LSB of) will solve the
  687.     problem.  ALL ARITHMETIC IS CARRIED OUT IN 32 BITS.  The final
  688.     Result will be automatically truncated to the maximum handleable
  689.     by the particular machine language (usually a word) when applied
  690.     to standard mnemonics.
  691.  
  692.     prec        UNARY
  693.  
  694.     20  ~exp    one's complement.
  695.     20  -exp    negation
  696.     20  !exp    not expression (returns 0 if exp non-zero, 1 if exp zero)
  697.     20  <exp    take LSB byte of a 16 bit expression
  698.     20  >exp    take MSB byte of an expression
  699.  
  700.             BINARY
  701.  
  702.     19  *        multiplication
  703.     19  /        division
  704.     19  %        mod
  705.     18  +        addition
  706.     18  -        subtraction
  707.     17  >>,<<   shift right, shift left
  708.     16  >,>=    greater, greater equal
  709.     16  <,<=    smaller, smaller equal
  710.     15  ==        equal to.  Try to use this instead of =
  711.     15  =        exactly the same as == (exists compatibility)
  712.     15  !=        not equal to
  713.     14  &        logical and
  714.     13  ^        logical xor
  715.     12  |        logical or
  716.     11  &&        left expression is true AND right expression is true
  717.     10  ||        left expression is true OR right expression is true
  718.      9  ?        if left expression is true, result is right expression,
  719.             else result is 0.    [10 ? 20] returns 20
  720.      8  []        group expressions
  721.      7  ,        separate expressions in list (also used in
  722.             addressing mode resolution, BE CAREFUL!
  723.  
  724.     Constants:
  725.  
  726.     nnn    decimal
  727.     0nnn    octal
  728.     %nnn    binary
  729.     $nnn    hex
  730.     'c      character
  731.     "cc.."  string (NOT zero terminated if in DC/DS/DV)
  732.     [exp]d    the constant expressions is evaluated and it's decimal
  733.         result turned into an ascii string.
  734.  
  735.     Symbols:
  736.  
  737.     ...    -holds CHECKSUM so far (of actual-generated stuff)
  738.     ..    -holds evaluated value in DV pseudo op
  739.     .name    -represents a temporary symbol name.  Temporary symbols
  740.          may be reused inside MACROS and between SUBROUTINES, but
  741.          may not be referenced across macros or across SUBROUTINEs.
  742.     .    -current program counter (as of the beginning of the
  743.          instruction).
  744.     name    -beginning with an alpha character and containing letters,
  745.          numbers, or '_'.  Represents some global symbol name.
  746.  
  747.  
  748. WHY codes:
  749.     Each bit in the WHY word (verbose option 1) is a reason (why
  750.     the assembler needs to do another pass), as follows:
  751.  
  752.     bit 0   expression in mnemonic not resolved
  753.     1   -
  754.     2   expression in a DC not resolved
  755.     3   expression in a DV not resolved (probably in DV's EQM symbol)
  756.     4   expression in a DV not resolved (could be in DV's EQM symbol)
  757.     5   expression in a DS not resolved
  758.     6   expression in an ALIGN not resolved
  759.     7   ALIGN: Relocatable origin not known (if in RORG at the time)
  760.     8   ALIGN: Normal origin not known    (if in ORG at the time)
  761.     9   EQU:   expression not resolved
  762.     10  EQU:   value mismatch from previous pass (phase error)
  763.     11  IF:     expression not resolved
  764.     12  REPEAT: expression not resolved
  765.  
  766.     13  a program label has been defined after it has been
  767.         referenced (forward reference) and thus we need another
  768.         pass
  769.     14  a program label's value is different from that of the
  770.         previous pass (phase error)
  771.  
  772.     Certain errors will cause the assembly to abort immediately, others
  773.     will wait until the current pass is other.    The remaining allow another
  774.     pass to occur in the hopes the error will fix itself.
  775.  
  776.  
  777. VERSIONS:
  778.  
  779.     V2.11
  780.     -Fixed <exp >exp bug, <exp now means LSB, >exp MSB (it used to
  781.      be reversed).
  782.     -Fixed many bugs in macros and other things
  783.     -Added automatic checksumming ... no more doing checksums manually!
  784.     -Added several new processors, including 6502.
  785.     -Source is now 16/32 bit int compatible, and will compile on an
  786.      IBM-PC (the ultimate portability test)
  787.  
  788.     V2.01
  789.  
  790.     -can now have REPEAT/REPEND's within macros
  791.     -fill field for DS.W is a word (used to be a byte fill)
  792.     -fill field for DS.L is a long (used to be a byte fill)
  793.  
  794.  
  795. \Rogue\Monster\
  796. else
  797.   echo "will not over write doc/dasm.doc"
  798. fi
  799. if [ `wc -c doc/dasm.doc | awk '{printf $1}'` -ne 19789 ]
  800. then
  801. echo `wc -c doc/dasm.doc | awk '{print "Got " $1 ", Expected " 19789}'`
  802. fi
  803. if `test ! -d src`
  804. then
  805.   mkdir src
  806.   echo "mkdir src"
  807. fi
  808. if `test ! -s src/test.asm`
  809. then
  810. echo "writing src/test.asm"
  811. cat > src/test.asm << '\Rogue\Monster\'
  812.  
  813.         trace   on
  814.  
  815. X        equ     $100
  816. IRAMSTART   equ     $80
  817.  
  818.         org     X
  819.         org     IRAMSTART
  820.  
  821. \Rogue\Monster\
  822. else
  823.   echo "will not over write src/test.asm"
  824. fi
  825. if [ `wc -c src/test.asm | awk '{printf $1}'` -ne 101 ]
  826. then
  827. echo `wc -c src/test.asm | awk '{print "Got " $1 ", Expected " 101}'`
  828. fi
  829. if `test ! -s src/tags`
  830. then
  831. echo "writing src/tags"
  832. cat > src/tags << '\Rogue\Monster\'
  833. eval exp.c /^eval(
  834. alphanum exp.c /^alphanum(
  835. evaltop exp.c /^evaltop(
  836. stackarg exp.c /^stackarg(
  837. doop exp.c /^doop(
  838. op_takelsb exp.c /^op_takelsb(
  839. op_takemsb exp.c /^op_takemsb(
  840. op_negate exp.c /^op_negate(
  841. op_invert exp.c /^op_invert(
  842. op_not exp.c /^op_not(
  843. op_mult exp.c /^op_mult(
  844. op_div exp.c /^op_div(
  845. op_mod exp.c /^op_mod(
  846. op_question exp.c /^op_question(
  847. op_add exp.c /^op_add(
  848. op_sub exp.c /^op_sub(
  849. op_shiftright exp.c /^op_shiftright(
  850. op_shiftleft exp.c /^op_shiftleft(
  851. op_greater exp.c /^op_greater(
  852. op_greatereq exp.c /^op_greatereq(
  853. op_smaller exp.c /^op_smaller(
  854. op_smallereq exp.c /^op_smallereq(
  855. op_eqeq exp.c /^op_eqeq(
  856. op_noteq exp.c /^op_noteq(
  857. op_andand exp.c /^op_andand(
  858. op_oror exp.c /^op_oror(
  859. op_xor exp.c /^op_xor(
  860. op_and exp.c /^op_and(
  861. op_or exp.c /^op_or(
  862. pushchar exp.c /^pushchar(
  863. pushhex exp.c /^pushhex(
  864. pushoct exp.c /^pushoct(
  865. pushdec exp.c /^pushdec(
  866. pushbin exp.c /^pushbin(
  867. pushstr exp.c /^pushstr(
  868. pushsymbol exp.c /^pushsymbol(
  869. main ftohex.c /^main(
  870. exiterr ftohex.c /^exiterr(
  871. convert ftohex.c /^convert(
  872. getwlh ftohex.c /^getwlh(
  873. puth ftohex.c /^puth(
  874. main main.c /^main(
  875. outlistfile main.c /^outlistfile(
  876. tabit main.c /^tabit(
  877. sftos main.c /^sftos(
  878. clearsegs main.c /^clearsegs(
  879. clearrefs main.c /^clearrefs(
  880. cleanup main.c /^cleanup(
  881. while main.c /^    while(
  882. findext main.c /^findext(
  883. rmnode main.c /^rmnode(
  884. parse main.c /^parse(
  885. findmne main.c /^findmne(
  886. v_macro main.c /^v_macro(
  887. addhashtable main.c /^addhashtable(
  888. hash1 main.c /^hash1(
  889. pushinclude main.c /^pushinclude(
  890. asmerr main.c /^asmerr(
  891. zmalloc main.c /^zmalloc(
  892. permalloc main.c /^permalloc(
  893. xbset main.c /^xbset(
  894. bcmp main.c /^bcmp(
  895. v_processor ops.c /^v_processor(
  896. v_mnemonic ops.c /^v_mnemonic(
  897. v_trace ops.c /^v_trace(
  898. v_list ops.c /^v_list(
  899. v_include ops.c /^v_include(
  900. v_seg ops.c /^v_seg(
  901. v_hex ops.c /^v_hex(
  902. gethexdig ops.c /^gethexdig(
  903. v_err ops.c /^v_err(
  904. v_dc ops.c /^v_dc(
  905. v_ds ops.c /^v_ds(
  906. v_org ops.c /^v_org(
  907. v_rorg ops.c /^v_rorg(
  908. v_rend ops.c /^v_rend(
  909. v_align ops.c /^v_align(
  910. v_subroutine ops.c /^v_subroutine(
  911. v_equ ops.c /^v_equ(
  912. v_eqm ops.c /^v_eqm(
  913. v_echo ops.c /^v_echo(
  914. v_set ops.c /^v_set(
  915. v_execmac ops.c /^v_execmac(
  916. v_end ops.c /^v_end(
  917. v_endm ops.c /^v_endm(
  918. v_mexit ops.c /^v_mexit(
  919. v_ifconst ops.c /^v_ifconst(
  920. v_ifnconst ops.c /^v_ifnconst(
  921. v_if ops.c /^v_if(
  922. v_else ops.c /^v_else(
  923. v_endif ops.c /^v_endif(
  924. v_repeat ops.c /^v_repeat(
  925. v_repend ops.c /^v_repend(
  926. generate ops.c /^generate(
  927. closegenerate ops.c /^closegenerate(
  928. genfill ops.c /^genfill(
  929. pushif ops.c /^pushif(
  930. setspecial symbols.c /^setspecial(
  931. findsymbol symbols.c /^findsymbol(
  932. createsymbol symbols.c /^createsymbol(
  933. hash1 symbols.c /^hash1(
  934. programlabel symbols.c /^programlabel(
  935. allocsymbol symbols.c /^allocsymbol(
  936. freesymbol symbols.c /^freesymbol(
  937. freesymbollist symbols.c /^freesymbollist(
  938. \Rogue\Monster\
  939. else
  940.   echo "will not over write src/tags"
  941. fi
  942. if [ `wc -c src/tags | awk '{printf $1}'` -ne 2807 ]
  943. then
  944. echo `wc -c src/tags | awk '{print "Got " $1 ", Expected " 2807}'`
  945. fi
  946. if `test ! -s src/test`
  947. then
  948. echo "writing src/test"
  949. cat > src/test << '\Rogue\Monster\'
  950.  
  951. run srcc:dasm test.asm -oram:x -f2 -v3
  952.  
  953. \Rogue\Monster\
  954. else
  955.   echo "will not over write src/test"
  956. fi
  957. if [ `wc -c src/test | awk '{printf $1}'` -ne 41 ]
  958. then
  959. echo `wc -c src/test | awk '{print "Got " $1 ", Expected " 41}'`
  960. fi
  961. if `test ! -s src/mne68705.c`
  962. then
  963. echo "writing src/mne68705.c"
  964. cat > src/mne68705.c << '\Rogue\Monster\'
  965.  
  966. /*
  967.  *  MNE68705.C
  968.  *
  969.  *  (c)Copyright 1988, Matthew Dillon, All Rights Reserved.
  970.  */
  971.  
  972. #include "asm.h"
  973.  
  974. #define AFSTD    AF_BYTEADR|AF_BYTEADRX|AF_WORDADR|AF_WORDADRX|AF_0X
  975.  
  976. extern void v_mnemonic();
  977.  
  978. MNE Mne68705[] = {
  979.     NULL, v_mnemonic, "adc", 0, AF_IMM8|AFSTD,
  980.     { 0xA9, 0xB9, 0xE9, 0xC9, 0xD9, 0xF9 },
  981.     NULL, v_mnemonic, "add", 0, AF_IMM8|AFSTD,
  982.     { 0xAB, 0xBB, 0xEB, 0xCB, 0xDB, 0xFB },
  983.     NULL, v_mnemonic, "and", 0, AF_IMM8|AFSTD,
  984.     { 0xA4, 0xB4, 0xE4, 0xC4, 0xD4, 0xF4 },
  985.     NULL, v_mnemonic, "asl", 0, AF_IMP|AF_BYTEADR|AF_BYTEADRX|AF_0X,
  986.     { 0x48, 0x38, 0x68, 0x78 },
  987.     NULL, v_mnemonic, "asla", 0,AF_IMP, { 0x48 },
  988.     NULL, v_mnemonic, "aslx", 0,AF_IMP, { 0x58 },
  989.     NULL, v_mnemonic, "asr", 0, AF_IMP|AF_BYTEADR|AF_BYTEADRX|AF_0X,
  990.     { 0x47, 0x37, 0x67, 0x77 },
  991.     NULL, v_mnemonic, "asra", 0,AF_IMP, { 0x47 },
  992.     NULL, v_mnemonic, "asrx", 0,AF_IMP, { 0x57 },
  993.     NULL, v_mnemonic, "bcc", 0, AF_REL, { 0x24 },
  994.     NULL, v_mnemonic, "bclr", MF_IMOD,AF_BITMOD, { 0x11 },
  995.     NULL, v_mnemonic, "bcs", 0, AF_REL, { 0x25 },
  996.     NULL, v_mnemonic, "beq", 0, AF_REL, { 0x27 },
  997.     NULL, v_mnemonic, "bhcc", 0,AF_REL, { 0x28 },
  998.     NULL, v_mnemonic, "bhcs", 0,AF_REL, { 0x29 },
  999.     NULL, v_mnemonic, "bhi", 0, AF_REL, { 0x22 },
  1000.     NULL, v_mnemonic, "bhs", 0, AF_REL, { 0x24 },
  1001.     NULL, v_mnemonic, "bih", 0, AF_REL, { 0x2F },
  1002.     NULL, v_mnemonic, "bil", 0, AF_REL, { 0x2E },
  1003.     NULL, v_mnemonic, "bit", 0, AF_IMM8|AFSTD,
  1004.     { 0xA5, 0xB5, 0xE5, 0xC5, 0xD5, 0xF5 },
  1005.     NULL, v_mnemonic, "blo", 0, AF_REL, { 0x25 },
  1006.     NULL, v_mnemonic, "bls", 0, AF_REL, { 0x23 },
  1007.     NULL, v_mnemonic, "bmc", 0, AF_REL, { 0x2C },
  1008.     NULL, v_mnemonic, "bmi", 0, AF_REL, { 0x2B },
  1009.     NULL, v_mnemonic, "bms", 0, AF_REL, { 0x2D },
  1010.     NULL, v_mnemonic, "bne", 0, AF_REL, { 0x26 },
  1011.     NULL, v_mnemonic, "bpl", 0, AF_REL, { 0x2A },
  1012.     NULL, v_mnemonic, "bra", 0, AF_REL, { 0x20 },
  1013.     NULL, v_mnemonic, "brn", 0, AF_REL, { 0x21 },
  1014.     NULL, v_mnemonic, "brclr", MF_IMOD|MF_REL,   AF_BITBRAMOD, { 0x01 },
  1015.     NULL, v_mnemonic, "brset", MF_IMOD|MF_REL,   AF_BITBRAMOD, { 0x00 },
  1016.     NULL, v_mnemonic, "bset", MF_IMOD,AF_BITMOD, { 0x10 },
  1017.     NULL, v_mnemonic, "bsr", 0, AF_REL, { 0xAD },
  1018.     NULL, v_mnemonic, "clc", 0, AF_IMP, { 0x98 },
  1019.     NULL, v_mnemonic, "cli", 0, AF_IMP, { 0x9A },
  1020.     NULL, v_mnemonic, "clr", 0, AF_IMP|AF_BYTEADR|AF_BYTEADRX|AF_0X,
  1021.     { 0x4F, 0x3F, 0x6F, 0x7F },
  1022.     NULL, v_mnemonic, "clra", 0,AF_IMP, { 0x4F },
  1023.     NULL, v_mnemonic, "clrx", 0,AF_IMP, { 0x5F },
  1024.     NULL, v_mnemonic, "cmp", 0, AF_IMM8|AFSTD,
  1025.     { 0xA1, 0xB1, 0xE1, 0xC1, 0xD1, 0xF1 },
  1026.     NULL, v_mnemonic, "com", 0, AF_IMP|AF_BYTEADR|AF_BYTEADRX|AF_0X,
  1027.     { 0x43, 0x33, 0x63, 0x73 },
  1028.     NULL, v_mnemonic, "coma", 0,AF_IMP, { 0x43 },
  1029.     NULL, v_mnemonic, "comx", 0,AF_IMP, { 0x53 },
  1030.     NULL, v_mnemonic, "cpx", 0, AF_IMM8|AFSTD,
  1031.     { 0xA3, 0xB3, 0xE3, 0xC3, 0xD3, 0xF3 },
  1032.     NULL, v_mnemonic, "dec", 0, AF_IMP|AF_BYTEADR|AF_BYTEADRX|AF_0X,
  1033.     { 0x4A, 0x3A, 0x6A, 0x7A },
  1034.     NULL, v_mnemonic, "deca", 0,AF_IMP, { 0x4A },
  1035.     NULL, v_mnemonic, "decx", 0,AF_IMP, { 0x5A },
  1036.     NULL, v_mnemonic, "dex", 0, AF_IMP, { 0x5A },
  1037.     NULL, v_mnemonic, "eor", 0, AF_IMM8|AFSTD,
  1038.     { 0xA8, 0xB8, 0xE8, 0xC8, 0xD8, 0xF8 },
  1039.     NULL, v_mnemonic, "inc", 0, AF_IMP|AF_BYTEADR|AF_BYTEADRX|AF_0X,
  1040.     { 0x4C, 0x3C, 0x6C, 0x7C },
  1041.     NULL, v_mnemonic, "inca", 0,AF_IMP, { 0x4C },
  1042.     NULL, v_mnemonic, "incx", 0,AF_IMP, { 0x5C },
  1043.     NULL, v_mnemonic, "inx", 0, AF_IMP, { 0x5C },
  1044.     NULL, v_mnemonic, "jmp", 0, AFSTD,
  1045.     { 0xBC, 0xEC, 0xCC, 0xDC, 0xFC },
  1046.     NULL, v_mnemonic, "jsr", 0, AFSTD,
  1047.     { 0xBD, 0xED, 0xCD, 0xDD, 0xFD },
  1048.     NULL, v_mnemonic, "lda", 0, AF_IMM8|AFSTD,
  1049.     { 0xA6, 0xB6, 0xE6, 0xC6, 0xD6, 0xF6 },
  1050.     NULL, v_mnemonic, "ldx", 0, AF_IMM8|AFSTD,
  1051.     { 0xAE, 0xBE, 0xEE, 0xCE, 0xDE, 0xFE },
  1052.     NULL, v_mnemonic, "lsl", 0, AF_IMP|AF_BYTEADR|AF_BYTEADRX|AF_0X,
  1053.     { 0x48, 0x38, 0x68, 0x78 },
  1054.     NULL, v_mnemonic, "lsla", 0,AF_IMP, { 0x48 },
  1055.     NULL, v_mnemonic, "lslx", 0,AF_IMP, { 0x58 },
  1056.     NULL, v_mnemonic, "lsr", 0, AF_IMP|AF_BYTEADR|AF_BYTEADRX|AF_0X,
  1057.     { 0x44, 0x34, 0x64, 0x74 },
  1058.     NULL, v_mnemonic, "lsra", 0,AF_IMP, { 0x44 },
  1059.     NULL, v_mnemonic, "lsrx", 0,AF_IMP, { 0x54 },
  1060.     NULL, v_mnemonic, "neg", 0, AF_IMP|AF_BYTEADR|AF_BYTEADRX|AF_0X,
  1061.     { 0x40, 0x30, 0x60, 0x70 },
  1062.     NULL, v_mnemonic, "nega", 0,AF_IMP, { 0x40 },
  1063.     NULL, v_mnemonic, "negx", 0,AF_IMP, { 0x50 },
  1064.     NULL, v_mnemonic, "nop", 0, AF_IMP, { 0x9D },
  1065.     NULL, v_mnemonic, "ora", 0, AF_IMM8|AFSTD,
  1066.     { 0xAA, 0xBA, 0xEA, 0xCA, 0xDA, 0xFA },
  1067.     NULL, v_mnemonic, "rol", 0, AF_IMP|AF_BYTEADR|AF_BYTEADRX|AF_0X,
  1068.     { 0x49, 0x39, 0x69, 0x79 },
  1069.     NULL, v_mnemonic, "rola", 0,AF_IMP, { 0x49 },
  1070.     NULL, v_mnemonic, "rolx", 0,AF_IMP, { 0x59 },
  1071.     NULL, v_mnemonic, "ror", 0, AF_IMP|AF_BYTEADR|AF_BYTEADRX|AF_0X,
  1072.     { 0x46, 0x36, 0x66, 0x76 },
  1073.     NULL, v_mnemonic, "rora", 0,AF_IMP, { 0x46 },
  1074.     NULL, v_mnemonic, "rorx", 0,AF_IMP, { 0x56 },
  1075.     NULL, v_mnemonic, "rsp", 0, AF_IMP, { 0x9C },
  1076.     NULL, v_mnemonic, "rti", 0, AF_IMP, { 0x80 },
  1077.     NULL, v_mnemonic, "rts", 0, AF_IMP, { 0x81 },
  1078.     NULL, v_mnemonic, "sbc", 0, AF_IMM8|AFSTD,
  1079.     { 0xA2, 0xB2, 0xE2, 0xC2, 0xD2, 0xF2 },
  1080.     NULL, v_mnemonic, "sec", 0, AF_IMP, { 0x99 },
  1081.     NULL, v_mnemonic, "sei", 0, AF_IMP, { 0x9B },
  1082.     NULL, v_mnemonic, "sta", 0, AFSTD,
  1083.     { 0xB7, 0xE7, 0xC7, 0xD7, 0xF7 },
  1084.     NULL, v_mnemonic, "stx", 0, AFSTD,
  1085.     { 0xBF, 0xEF, 0xCF, 0xDF, 0xFF },
  1086.     NULL, v_mnemonic, "sub", 0, AF_IMM8|AFSTD,
  1087.     { 0xA0, 0xB0, 0xE0, 0xC0, 0xD0, 0xF0 },
  1088.     NULL, v_mnemonic, "swi", 0, AF_IMP, { 0x83 },
  1089.     NULL, v_mnemonic, "tax", 0, AF_IMP, { 0x97 },
  1090.     NULL, v_mnemonic, "tst", 0, AF_IMP|AF_BYTEADR|AF_BYTEADRX|AF_0X,
  1091.     { 0x4D, 0x3D, 0x6D, 0x7D },
  1092.     NULL, v_mnemonic, "tsta", 0,AF_IMP, { 0x4D },
  1093.     NULL, v_mnemonic, "tstx", 0,AF_IMP, { 0x5D },
  1094.     NULL, v_mnemonic, "txa", 0, AF_IMP, { 0x9F },
  1095.     NULL
  1096. };
  1097.  
  1098. \Rogue\Monster\
  1099. else
  1100.   echo "will not over write src/mne68705.c"
  1101. fi
  1102. if [ `wc -c src/mne68705.c | awk '{printf $1}'` -ne 5823 ]
  1103. then
  1104. echo `wc -c src/mne68705.c | awk '{print "Got " $1 ", Expected " 5823}'`
  1105. fi
  1106. if `test ! -s src/ftohex.c`
  1107. then
  1108. echo "writing src/ftohex.c"
  1109. cat > src/ftohex.c << '\Rogue\Monster\'
  1110.  
  1111. /*
  1112.  *  FTOHEX.C
  1113.  *
  1114.  *  (c)Copyright 1988, Matthew Dillon, All Rights Reserved.
  1115.  *
  1116.  *  FTOHEX format infile [outfile]
  1117.  *
  1118.  *  format: format used when assembling (asm705/asm65)
  1119.  *        1,2,3        -generate straight hex file
  1120.  *
  1121.  *  compilable on an ibm-pc or Amiga  _fmode is for Lattice C on the ibm,
  1122.  *  is IGNORED by Aztec C on the Amiga.  Note that INT and CHAR are not
  1123.  *  used as ibm's lattice C uses 16 bit ints and unsigned chars.  Change
  1124.  *  as needed.    No guarentees for the IBMPC version.
  1125.  */
  1126.  
  1127. #include <stdio.h>
  1128.  
  1129. #ifdef IBM
  1130. typedef char ubyte;
  1131. typedef unsigned uword;
  1132. typedef int void;
  1133. #else
  1134. typedef unsigned char ubyte;
  1135. typedef unsigned short uword;
  1136. #endif
  1137.  
  1138. #define PERLINE 16
  1139.  
  1140. extern long ftell();
  1141. extern void fseek();
  1142. extern uword getwlh();
  1143. extern void  puth();
  1144.  
  1145. uword _fmode = 0;
  1146.  
  1147. main(ac, av)
  1148. ubyte *av[];
  1149. short ac;
  1150. {
  1151.     short format;
  1152.     FILE *infile;
  1153.     FILE *outfile;
  1154.  
  1155.     _fmode = 0x8000;
  1156.     if (ac < 3) {
  1157.     puts("FTOHEX format infile [outfile]");
  1158.     puts("format 1,2, or 3.  3=raw");
  1159.     puts("(C)Copyright 1987 by Matthew Dillon, All Rights Reserved");
  1160.     exit(1);
  1161.     }
  1162.     format = atoi(av[1]);
  1163.     if (format < 1 || format > 3)
  1164.     exiterr("specify infile format 1, 2, or 3");
  1165.     infile = fopen(av[2], "r");
  1166.     if (infile == NULL)
  1167.     exiterr("unable to open input file");
  1168.     outfile = (av[3]) ? fopen(av[3], "w") : stdout;
  1169.     if (outfile == NULL)
  1170.     exiterr("unable to open output file");
  1171.     convert(format, infile, outfile);
  1172.     fclose(infile);
  1173.     fclose(outfile);
  1174. }
  1175.  
  1176. exiterr(str)
  1177. ubyte *str;
  1178. {
  1179.     fputs(str, stderr);
  1180.     fputs("\n", stderr);
  1181.     exit(1);
  1182. }
  1183.  
  1184. /*
  1185.  *  Formats:
  1186.  *
  1187.  *  1:    origin (word:lsb,msb) + data
  1188.  *  2:    origin (word:lsb,msb) + length (word:lsb,msb) + data  (repeat)
  1189.  *  3:    data
  1190.  *
  1191.  *  Hex output:
  1192.  *
  1193.  *  :lloooo00(ll bytes hex code)cc      ll=# of bytes
  1194.  *                    oooo=origin
  1195.  *                    cc=invert of checksum all codes
  1196.  */
  1197.  
  1198. convert(format, in, out)
  1199. short format;
  1200. FILE *in;
  1201. FILE *out;
  1202. {
  1203.     uword org = 0;
  1204.     uword idx;
  1205.     long len;
  1206.     ubyte buf[256];
  1207.  
  1208.     if (format < 3)
  1209.     org = getwlh(in);
  1210.     if (format == 2) {
  1211.     len = getwlh(in);
  1212.     } else {
  1213.     long begin = ftell(in);
  1214.     fseek(in, 0L, 2);
  1215.     len = ftell(in) - begin;
  1216.     fseek(in, begin, 0);
  1217.     }
  1218.     for (;;) {
  1219.     while (len > 0) {
  1220.         register ubyte chk;
  1221.         register short i;
  1222.  
  1223.         idx = (len > PERLINE) ? PERLINE : len;
  1224.         fread(buf, idx, 1, in);
  1225.         putc(':', out);
  1226.         puth(idx, out);
  1227.         puth(org >> 8, out);
  1228.         puth(org & 0xFF, out);
  1229.         putc('0', out);
  1230.         putc('0', out);
  1231.         chk = idx + (org >> 8) + (org & 0xFF);
  1232.         for (i = 0; i < idx; ++i) {
  1233.         chk += buf[i];
  1234.         puth(buf[i], out);
  1235.         }
  1236.         puth((ubyte)-chk, out);
  1237.         putc('\r', out);
  1238.         putc('\n', out);
  1239.         len -= idx;
  1240.         org += idx;
  1241.     }
  1242.     if (format == 2) {
  1243.         org = getwlh(in);
  1244.         if (feof(in))
  1245.         break;
  1246.         len = getwlh(in);
  1247.     } else {
  1248.         break;
  1249.     }
  1250.     }
  1251.     fprintf(out, ":00000001FF\r\n");
  1252. }
  1253.  
  1254. uword
  1255. getwlh(in)
  1256. FILE *in;
  1257. {
  1258.     uword result;
  1259.  
  1260.     result = getc(in);
  1261.     result += getc(in) << 8;
  1262.     return(result);
  1263. }
  1264.  
  1265. void
  1266. puth(c, out)
  1267. ubyte c;
  1268. FILE *out;
  1269. {
  1270.     static ubyte dig[] = { "0123456789ABCDEF" };
  1271.     putc(dig[c>>4], out);
  1272.     putc(dig[c&15], out);
  1273. }
  1274.  
  1275. \Rogue\Monster\
  1276. else
  1277.   echo "will not over write src/ftohex.c"
  1278. fi
  1279. if [ `wc -c src/ftohex.c | awk '{printf $1}'` -ne 3133 ]
  1280. then
  1281. echo `wc -c src/ftohex.c | awk '{print "Got " $1 ", Expected " 3133}'`
  1282. fi
  1283. if `test ! -s src/symbols.c`
  1284. then
  1285. echo "writing src/symbols.c"
  1286. cat > src/symbols.c << '\Rogue\Monster\'
  1287.  
  1288. /*
  1289.  *  SYMBOLS.C
  1290.  *
  1291.  *  (c)Copyright 1988, Matthew Dillon, All Rights Reserved.
  1292.  */
  1293.  
  1294. #include "asm.h"
  1295.  
  1296. extern uword hash1();
  1297.  
  1298. static SYMBOL org;
  1299. static SYMBOL special;
  1300. static SYMBOL specchk;
  1301.  
  1302. void
  1303. setspecial(value, flags)
  1304. {
  1305.     special.value = value;
  1306.     special.flags = flags;
  1307. }
  1308.  
  1309. SYMBOL *
  1310. findsymbol(str, len)
  1311. ubyte *str;
  1312. short len;
  1313. {
  1314.     register uword h1;
  1315.     register SYMBOL *sym;
  1316.     ubyte buf[64];
  1317.     static SYMBOL org;
  1318.     short n;
  1319.  
  1320.     if (str[0] == '.') {
  1321.     if (len == 1) {
  1322.         if (Csegment->flags & SF_RORG) {
  1323.         org.flags = Csegment->rflags & SYM_UNKNOWN;
  1324.         org.value = Csegment->rorg;
  1325.         } else {
  1326.         org.flags = Csegment->flags & SYM_UNKNOWN;
  1327.         org.value = Csegment->org;
  1328.         }
  1329.         return(&org);
  1330.     }
  1331.     if (len == 2 && str[1] == '.')
  1332.         return(&special);
  1333.     if (len == 3 && str[1] == '.' && str[2] == '.') {
  1334.         specchk.flags = 0;
  1335.         specchk.value = CheckSum;
  1336.         return(&specchk);
  1337.     }
  1338.     sprintf(buf, "%ld", Localindex);
  1339.     n = strlen(buf);
  1340.     bmov(str, buf+n, len);
  1341.     len += n;
  1342.     str = buf;
  1343.     }
  1344.     h1 = hash1(str, len);
  1345.     for (sym = SHash[h1]; sym; sym = sym->next) {
  1346.     if (sym->namelen == len && bcmp(sym->name, str, len))
  1347.         break;
  1348.     }
  1349.     return(sym);
  1350. }
  1351.  
  1352. SYMBOL *
  1353. createsymbol(str, len)
  1354. ubyte *str;
  1355. short len;
  1356. {
  1357.     register SYMBOL *sym;
  1358.     register uword h1;
  1359.     ubyte buf[64];
  1360.  
  1361.     if (str[0] == '.') {
  1362.     short n;
  1363.     sprintf(buf, "%ld", Localindex);
  1364.     n = strlen(buf);
  1365.     bmov(str, buf+n, len);
  1366.     len += n;
  1367.     str = buf;
  1368.     }
  1369.     sym = (SYMBOL *)allocsymbol();
  1370.     sym->name = permalloc(len+1);
  1371.     bmov(str, sym->name, len);        /*  permalloc zero's the array for us */
  1372.     sym->namelen = len;
  1373.     h1 = hash1(str, len);
  1374.     sym->next = SHash[h1];
  1375.     sym->flags= SYM_UNKNOWN;
  1376.     SHash[h1] = sym;
  1377.     return(sym);
  1378. }
  1379.  
  1380. static uword
  1381. hash1(str, len)
  1382. register ubyte *str;
  1383. register short len;
  1384. {
  1385.     register uword result = 0;
  1386.  
  1387.     while (len--)
  1388.     result = (result << 2) ^ *str++;
  1389.     return(result & SHASHAND);
  1390. }
  1391.  
  1392. /*
  1393.  *  Label Support Routines
  1394.  */
  1395.  
  1396. void
  1397. programlabel()
  1398. {
  1399.     register uword len;
  1400.     register SYMBOL *sym;
  1401.     register SEGMENT *cseg = Csegment;
  1402.     register ubyte *str;
  1403.     ubyte   rorg = cseg->flags & SF_RORG;
  1404.     ubyte   cflags = (rorg) ? cseg->rflags : cseg->flags;
  1405.     ulong   pc = (rorg) ? cseg->rorg : cseg->org;
  1406.  
  1407.     Plab = cseg->org;
  1408.     Pflags = cseg->flags;
  1409.     str = Av[0];
  1410.     if (*str == 0)
  1411.     return;
  1412.     len = strlen(str);
  1413.     if (str[len-1] == ':')
  1414.     --len;
  1415.  
  1416.     /*
  1417.      *    Redo:    unknown and referenced
  1418.      *        referenced and origin not known
  1419.      *        known and phase error    (origin known)
  1420.      */
  1421.  
  1422.     if (sym = findsymbol(str, len)) {
  1423.     if ((sym->flags & (SYM_UNKNOWN|SYM_REF)) == (SYM_UNKNOWN|SYM_REF)) {
  1424.         ++Redo;
  1425.         Redo_why |= 1 << 13;
  1426.         if (Xdebug)
  1427.         printf("redo 13: '%s' %04x %04x\n", sym->name, sym->flags, cflags);
  1428.     } else
  1429.     if ((cflags & SYM_UNKNOWN) && (sym->flags & SYM_REF)) {
  1430.         ++Redo;
  1431.         Redo_why |= 1 << 13;
  1432.     } else
  1433.     if (!(cflags & SYM_UNKNOWN) && !(sym->flags & SYM_UNKNOWN)) {
  1434.         if (pc != sym->value) {
  1435.         printf("mismatch %10s %s  pc: %s\n", sym->name, sftos(sym->value, sym->flags), sftos(pc, cflags & 7));
  1436.         asmerr(17,0);
  1437.         ++Redo;
  1438.         Redo_why |= 1 << 14;
  1439.         }
  1440.     }
  1441.     } else {
  1442.     sym = createsymbol(str, len);
  1443.     }
  1444.     sym->value = pc;
  1445.     sym->flags = (sym->flags & ~SYM_UNKNOWN) | (cflags & SYM_UNKNOWN);
  1446. }
  1447.  
  1448. SYMBOL *SymAlloc;
  1449.  
  1450. SYMBOL *
  1451. allocsymbol()
  1452. {
  1453.     SYMBOL *sym;
  1454.  
  1455.     if (SymAlloc) {
  1456.     sym = SymAlloc;
  1457.     SymAlloc = SymAlloc->next;
  1458.     bzero(sym, sizeof(SYMBOL));
  1459.     } else {
  1460.     sym = (SYMBOL *)permalloc(sizeof(SYMBOL));
  1461.     }
  1462.     return(sym);
  1463. }
  1464.  
  1465. void
  1466. freesymbol(sym)
  1467. SYMBOL *sym;
  1468. {
  1469.     sym->next = SymAlloc;
  1470.     SymAlloc = sym;
  1471. }
  1472.  
  1473. void
  1474. freesymbollist(sym)
  1475. SYMBOL *sym;
  1476. {
  1477.     register SYMBOL *next;
  1478.  
  1479.     while (sym) {
  1480.     next = sym->next;
  1481.     sym->next = SymAlloc;
  1482.     if (sym->flags & SYM_STRING)
  1483.         free(sym->string);
  1484.     SymAlloc = sym;
  1485.     sym = next;
  1486.     }
  1487. }
  1488.  
  1489. \Rogue\Monster\
  1490. else
  1491.   echo "will not over write src/symbols.c"
  1492. fi
  1493. if [ `wc -c src/symbols.c | awk '{printf $1}'` -ne 3830 ]
  1494. then
  1495. echo `wc -c src/symbols.c | awk '{print "Got " $1 ", Expected " 3830}'`
  1496. fi
  1497. echo "Finished archive 3 of 3"
  1498. # if you want to concatenate archives, remove anything after this line
  1499. exit
  1500. -- 
  1501. Bob Page, U of Lowell CS Dept.  page@swan.ulowell.edu  ulowell!page
  1502. Have five nice days.
  1503.